package kotlinx.coroutines

import kotlinx.cinterop.*
import platform.ohos.*

@OptIn(ExperimentalForeignApi::class)
private lateinit var tsfn: napi_threadsafe_function

@OptIn(ExperimentalForeignApi::class)
private var mainTid: Int = coroutines_get_pid()

@OptIn(ExperimentalForeignApi::class)
internal fun isMainThread(): Boolean {
    return coroutines_get_tid() == mainTid
}

@OptIn(ExperimentalForeignApi::class)
private fun callJSInThreadSafeFunction(
    env: napi_env?,
    value: napi_value?,
    context: COpaquePointer?,
    data: COpaquePointer?
) {
    val blockRef = data?.asStableRef<() -> Unit>() ?: return
    val block = blockRef.get()
    blockRef.dispose()
    return block.invoke()
}

@OptIn(ExperimentalForeignApi::class)
public fun initMainHandler(env: napi_env) {
    tsfn = createTSFWithCallback(
        env,
        "MainHandlerWorker",
        staticCFunction(::callJSInThreadSafeFunction)
    )!!
    OH_LOG_Print(LOG_APP, LOG_INFO, 0u, "MainHandler", "initMainHandler success")
}

@OptIn(ExperimentalForeignApi::class)
internal fun runOnMainThread(immediately: Boolean, block: () -> Unit) {
    if (immediately && isMainThread()) {
        block()
    } else {
        val ref = StableRef.create(block)
        callTSFWithData(tsfn, ref.asCPointer())
    }
}

